package classloader;

public class classloadmain {

    public static void main(String[] args) {
        //no load
//        loadtest1 loadtest1;


        //load+init
//        loadtest1 loadtest1 = new loadtest1();


        //no load
        /**
         * 不触发类加载是如何得到【oadtest1.noInit】值得喃？
         * javap -verbose classloadmain
         *Constant pool:
         *    #1 = Methodref          #7.#16         // java/lang/Object."<init>":()V
         *    #2 = Fieldref           #17.#18        // java/lang/System.out:Ljava/io/PrintStream;
         *    #3 = Class              #19            // classloader/loadtest1
         *    #4 = String             #20            // args = [noInit]
         *    #5 = Methodref          #21.#22        // java/io/PrintStream.println:(Ljava/lang/String;)V
         *    #6 = Class              #23            // classloader/classloadmain
         *    #7 = Class              #24            // java/lang/Object
         *    #8 = Utf8               <init>
         *    #9 = Utf8               ()V
         *   #10 = Utf8               Code
         *   #11 = Utf8               LineNumberTable
         *   #12 = Utf8               main
         *   #13 = Utf8               ([Ljava/lang/String;)V
         *   #14 = Utf8               SourceFile
         *   #15 = Utf8               classloadmain.java
         *   #16 = NameAndType        #8:#9          // "<init>":()V
         *   #17 = Class              #25            // java/lang/System
         *   #18 = NameAndType        #26:#27        // out:Ljava/io/PrintStream;
         *   #19 = Utf8               classloader/loadtest1
         *   #20 = Utf8               args = [noInit]
         *   #21 = Class              #28            // java/io/PrintStream
         *   #22 = NameAndType        #29:#30        // println:(Ljava/lang/String;)V
         *   #23 = Utf8               classloader/classloadmain
         *
         *   注意到这里不会调用loadtet1的初始化方法
         *   这里的#20直接把loadtest1.noInit解析为常量池中的字面常量了
         */
//        System.out.println("args = [" + loadtest1.noInit + "]");


        //load_init
        //注意到这里会直接调用loadtest1的init方法
        /**
         *   #2 = Fieldref           #17.#18        // java/lang/System.out:Ljava/io/PrintStream;
         *    #3 = Fieldref           #19.#20        // classloader/loadtest1.Init:Ljava/lang/String;
         *    #4 = InvokeDynamic      #0:#24         // #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
         *    #5 = Methodref          #25.#26        // java/io/PrintStream.println:(Ljava/lang/String;)V
         *    #6 = Class              #27            // classloader/classloadmain
         *    #7 = Class              #28            // java/lang/Object
         *    #8 = Utf8               <init>
         *    #9 = Utf8               ()V
         *   #10 = Utf8               Code
         *   #11 = Utf8               LineNumberTable
         *   #12 = Utf8               main
         *   #13 = Utf8               ([Ljava/lang/String;)V
         *   #14 = Utf8               SourceFile
         *   #15 = Utf8               classloadmain.java
         *   #16 = NameAndType        #8:#9          // "<init>":()V
         *   #17 = Class              #29            // java/lang/System
         *   #18 = NameAndType        #30:#31        // out:Ljava/io/PrintStream;
         *   #19 = Class              #32            // classloader/loadtest1
         *
         *   注意#19这里就已经采用了loadtest1的符号引用了
         *   这里会进行loadtest1的初始化
          */
        System.out.println("args = [" + loadtest1.Init + "]");
    }
}
